using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using System.IO;
using System.Windows;

namespace GameOverlayWPF
{
    public class AuthService
    {
        private static readonly HttpClient client = new HttpClient();
        private static readonly string TokenFilePath = Path.Combine(
            Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
            "GameOverlayWPF",
            "token.txt"
        );
        private static string? _currentToken = null;
        private static UserInfo? _currentUser = null;

        static AuthService()
        {
            try
            {
                // 确保目录存在
                var directory = Path.GetDirectoryName(TokenFilePath);
                if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
                {
                    try
                    {
                        Directory.CreateDirectory(directory);
                    }
                    catch (UnauthorizedAccessException ex)
                    {
                        System.Diagnostics.Debug.WriteLine($"无法创建token目录（权限不足）: {ex.Message}");
                        // 继续执行，不阻止应用启动
                    }
                    catch (IOException ex)
                    {
                        System.Diagnostics.Debug.WriteLine($"创建token目录失败（IO错误）: {ex.Message}");
                        // 继续执行，不阻止应用启动
                    }
                }

                // 尝试从文件加载令牌
                LoadTokenFromFile();
            }
            catch (Exception ex)
            {
                // 静态构造函数中的异常非常危险，必须全部捕获
                System.Diagnostics.Debug.WriteLine($"AuthService静态构造函数异常: {ex.Message}");
                // 不重新抛出，确保类可以被初始化
            }
        }

        // 用户登录
        public static async Task<LoginResult> LoginAsync(string username, string password)
        {
            try
            {
                var loginData = new
                {
                    username = username,
                    password = password
                };

                var json = JsonConvert.SerializeObject(loginData);
                var content = new StringContent(json, Encoding.UTF8, "application/json");

                var response = await client.PostAsync("http://113.45.182.203:3000/api/login", content);

                if (response.IsSuccessStatusCode)
                {
                    var responseContent = await response.Content.ReadAsStringAsync();
                    var result = JsonConvert.DeserializeObject<LoginResult>(responseContent);

                    if (result != null && result.Success && !string.IsNullOrEmpty(result.Token))
                    {
                        _currentToken = result.Token;
                        _currentUser = result.User;

                        // 保存令牌到文件
                        SaveTokenToFile(result.Token, result.User);

                        System.Diagnostics.Debug.WriteLine($"登录成功: {result.User?.Username}");
                        return result;
                    }
                    else
                    {
                        throw new Exception("登录响应格式错误");
                    }
                }
                else
                {
                    var errorContent = await response.Content.ReadAsStringAsync();
                    ErrorResponse? errorResult = null;
                    LoginResult? loginResult = null;

                    try
                    {
                        // 先尝试解析为ErrorResponse
                        errorResult = JsonConvert.DeserializeObject<ErrorResponse>(errorContent);
                    }
                    catch
                    {
                        // 如果无法解析为ErrorResponse，尝试解析为LoginResult（可能API返回的是LoginResult格式的错误）
                        try
                        {
                            loginResult = JsonConvert.DeserializeObject<LoginResult>(errorContent);
                        }
                        catch
                        {
                            // 如果都无法解析，使用默认消息
                        }
                    }

                    // 优先使用ErrorResponse的Message，然后是LoginResult的Message，最后是默认消息
                    var errorMessage = errorResult?.Message ?? loginResult?.Message ?? $"登录失败: HTTP {response.StatusCode}";
                    
                    // 如果没有具体的错误消息，根据状态码提供更友好的提示
                    if (string.IsNullOrEmpty(errorMessage) || errorMessage.Contains("HTTP"))
                    {
                        if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized)
                        {
                            errorMessage = "用户名或密码错误";
                        }
                        else if (response.StatusCode == System.Net.HttpStatusCode.NotFound)
                        {
                            errorMessage = "登录接口不存在";
                        }
                        else if (response.StatusCode == System.Net.HttpStatusCode.InternalServerError)
                        {
                            errorMessage = "服务器内部错误，请稍后重试";
                        }
                        else
                        {
                            errorMessage = $"登录失败: {response.StatusCode}";
                        }
                    }
                    
                    System.Diagnostics.Debug.WriteLine($"登录失败: {errorMessage}");
                    throw new Exception(errorMessage);
                }
            }
            catch (HttpRequestException ex)
            {
                System.Diagnostics.Debug.WriteLine($"网络请求错误: {ex.Message}");
                throw new Exception($"网络连接失败: {ex.Message}");
            }
            catch (TaskCanceledException ex)
            {
                System.Diagnostics.Debug.WriteLine($"请求超时: {ex.Message}");
                throw new Exception("请求超时，请检查网络连接");
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"登录错误: {ex.Message}");
                throw;
            }
        }

        // 使用令牌访问受保护的API
        public static async Task<T> GetProtectedDataAsync<T>(string token, string endpoint)
        {
            try
            {
                client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);

                var response = await client.GetAsync($"http://113.45.182.203:3000{endpoint}");

                if (response.IsSuccessStatusCode)
                {
                    var responseContent = await response.Content.ReadAsStringAsync();
                    return JsonConvert.DeserializeObject<T>(responseContent) ?? throw new Exception("响应数据为空");
                }
                else
                {
                    var errorContent = await response.Content.ReadAsStringAsync();
                    ErrorResponse? errorResult = null;

                    try
                    {
                        errorResult = JsonConvert.DeserializeObject<ErrorResponse>(errorContent);
                    }
                    catch
                    {
                        // 如果无法解析错误响应，使用默认消息
                    }

                    var errorMessage = errorResult?.Message ?? $"API请求失败: HTTP {response.StatusCode}";
                    System.Diagnostics.Debug.WriteLine(errorMessage);
                    throw new Exception(errorMessage);
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"API请求错误: {ex.Message}");
                throw;
            }
        }

        // 获取当前令牌
        public static string? GetCurrentToken()
        {
            return _currentToken;
        }

        // 获取当前用户信息
        public static UserInfo? GetCurrentUser()
        {
            return _currentUser;
        }

        // 检查是否已登录
        public static bool IsLoggedIn()
        {
            return !string.IsNullOrEmpty(_currentToken);
        }

        // 登出
        public static void Logout()
        {
            _currentToken = null;
            _currentUser = null;

            // 清除令牌文件
            try
            {
                if (File.Exists(TokenFilePath))
                {
                    File.Delete(TokenFilePath);
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"删除令牌文件失败: {ex.Message}");
            }

            // 清除Authorization头
            client.DefaultRequestHeaders.Authorization = null;
        }

        // 从文件加载令牌
        private static void LoadTokenFromFile()
        {
            try
            {
                if (File.Exists(TokenFilePath))
                {
                    var tokenData = File.ReadAllText(TokenFilePath);
                    if (!string.IsNullOrEmpty(tokenData))
                    {
                        // 简单存储：第一行是token，第二行是用户信息JSON（可选）
                        var lines = tokenData.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
                        if (lines.Length > 0 && !string.IsNullOrEmpty(lines[0]))
                        {
                            _currentToken = lines[0];

                            // 如果有用户信息，尝试解析
                            if (lines.Length > 1 && !string.IsNullOrEmpty(lines[1]))
                            {
                                try
                                {
                                    _currentUser = JsonConvert.DeserializeObject<UserInfo>(lines[1]);
                                }
                                catch (JsonException jsonEx)
                                {
                                    System.Diagnostics.Debug.WriteLine($"解析用户信息失败: {jsonEx.Message}");
                                    // 忽略用户信息解析错误，不影响token加载
                                }
                            }

                            // 设置Authorization头
                            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _currentToken);

                            System.Diagnostics.Debug.WriteLine("从文件加载令牌成功");
                        }
                    }
                }
            }
            catch (UnauthorizedAccessException ex)
            {
                System.Diagnostics.Debug.WriteLine($"加载令牌文件失败（权限不足）: {ex.Message}");
            }
            catch (IOException ex)
            {
                System.Diagnostics.Debug.WriteLine($"加载令牌文件失败（文件被锁定或IO错误）: {ex.Message}");
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"加载令牌文件失败（未知错误）: {ex.Message}");
            }
        }

        // 保存令牌到文件
        private static void SaveTokenToFile(string token, UserInfo? user)
        {
            try
            {
                var tokenData = token;
                if (user != null)
                {
                    var userJson = JsonConvert.SerializeObject(user);
                    tokenData += Environment.NewLine + userJson;
                }

                File.WriteAllText(TokenFilePath, tokenData);
                System.Diagnostics.Debug.WriteLine("令牌已保存到文件");
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"保存令牌文件失败: {ex.Message}");
            }
        }
    }

    // 数据模型
    public class LoginResult
    {
        [JsonProperty("success")]
        public bool Success { get; set; }

        [JsonProperty("message")]
        public string? Message { get; set; }

        [JsonProperty("token")]
        public string? Token { get; set; }

        [JsonProperty("user")]
        public UserInfo? User { get; set; }
    }

    public class UserInfo
    {
        [JsonProperty("id")]
        public int Id { get; set; }

        [JsonProperty("username")]
        public string? Username { get; set; }

        [JsonProperty("avatar")]
        public string? Avatar { get; set; }
    }

    public class ErrorResponse
    {
        [JsonProperty("success")]
        public bool Success { get; set; }

        [JsonProperty("message")]
        public string? Message { get; set; }
    }
}

